#include "logsimpl.h"
#include "tablestruct.h"

CLogsImpl::CLogsImpl(void)
{
}
CLogsImpl::~CLogsImpl(void)
{
    logi("CLoginImpl::~CLoginImpl");
}
HRESULT CLogsImpl::Init(IBase* pRot, IBase* pBase)
{
    HRESULT hr = S_OK;
    rc_error(pRot != NULL, E_FAIL);
    hr = pRot->QueryInterface(IID_IRot, (void**)&m_pRot);
    rc_error(hr == S_OK, E_FAIL);

    hr = GetRuleFiles();
    rc_error(hr == S_OK, E_FAIL);

    return S_OK;
}
HRESULT CLogsImpl::Uninit()
{
    return S_OK;
}
HRESULT CLogsImpl::Start(_pid_t pid, unsigned int type)
{
    HRESULT hr = S_OK;
    hr = m_pRot->GetObject(CLSID_CLogDataBase, IID_ILogDataBase, (IBase**)&m_pILogDataBase);
    rc_error(hr == S_OK, E_FAIL);
    rc_error(m_pILogDataBase.m_p != INULL, E_FAIL);

    // hr = LoadRuleFiles();

    CTimeThread::SetMilliSecond(30 * 1000);
    CTimeThread::StartThread();

    int rc = S_ERROR;
    rc = CSemThread::Start_Thread();
    rc_error(rc == S_SUCCESS, S_ERROR);

    return S_OK;
}
HRESULT CLogsImpl::Stop(unsigned int exit)
{
    HRESULT hr = S_OK;

    CSemThread::Stop_Thread();

    logi("CTimeThread::Stop_Tm_Thread");
    CTimeThread::StopThread();

    return hr;
}

HRESULT CLogsImpl::PostLog(UCHAR* pBuf, ULONG Size)
{
    rc_error(pBuf != NULL, E_FAIL);
    rc_error(Size != 0, E_FAIL);

    LogDataPtr ptr = new LogData(pBuf, Size);
    rc_error(ptr != NULL, E_FAIL);

    LogDataPtr ptr1 = new LogData(pBuf, Size);
    rc_error(ptr1 != NULL, E_FAIL);

    SYNC_OBJ(&m_lock);
    {
        m_ListJson.push_back(ptr);
        m_ListJson.push_back(ptr1);
    }
    return PostSem();
}

HRESULT CLogsImpl::AddObject(LPCSTR name, UINT len, IBase* pFilter)
{
    return S_OK;
}
HRESULT CLogsImpl::ReleaseObject(LPCSTR name, UINT len)
{
    return S_OK;
}
HRESULT CLogsImpl::Sem_Thread_Run()
{
    HRESULT hr = S_OK;

    TaskList listTemp;
    {
        SYNC_OBJ(&m_lock);
        listTemp.splice(listTemp.begin(), m_ListJson);
    }

    TaskListIterator it = listTemp.begin();
    for (; it != listTemp.end();) {
        ProcessTask(*it);
        delete *it;
        ++it;
    }

    return hr;
}

void get_file_cb_func(const basic_tchar* szPath, void* context)
{
    rc_return(szPath != NULL);
    rc_return(context != NULL);

    path_string strPath(szPath);
    size_t index = strPath.find(_T(".xdt"));
    if (index == path_string::npos) {
    } else {
        wdebug_view(szPath) wdebug_view(_T("\n"));
        CLogsImpl* p = static_cast<CLogsImpl*>(context);
        p->PushFile(strPath.c_str());
    }
}
HRESULT CLogsImpl::GetRuleFiles()
{
    basestring strPath = GetExePathString();
    get_files((basic_tchar*)strPath.c_str(), get_file_cb_func, this);
    return S_OK;
}

HRESULT CLogsImpl::LoadRuleFiles()
{
    RuleListIterator it = m_RuleFiles.begin();
    while (it != m_RuleFiles.end()) {
        ReadRuleFile(*it);
        ++it;
    }
    return S_OK;
}
HRESULT CLogsImpl::PushFile(const basic_tchar* file)
{
    m_RuleFiles.push_back(file);
    return S_OK;
}
HRESULT CLogsImpl::UploadTask()
{
    HRESULT hr = S_OK;

    return hr;
}
HRESULT CLogsImpl::SendSemThread()
{
    HRESULT hr = S_OK;

    return hr;
}
HRESULT CLogsImpl::ProcessTask(LogDataPtr cmd)
{
    unsigned char* p = cmd->GetData();
    rc_error(p != NULL, E_FAIL);
    unsigned long len = cmd->GetLen();
    rc_error(len != 0, E_FAIL);

    m_pILogDataBase->InsertTable(p, len);

    return S_OK;
}

HRESULT CLogsImpl::ReadRuleFile(const path_string& file)
{
    HRESULT hr = S_OK;

    unsigned long ulen = 0;
    UCharArrayPtr pBuf = ReadFileMem(file, ulen);
    rc_error(ulen > 0, E_FAIL);
    rc_error(pBuf.m_p != NULL, E_FAIL);

    JsonSafePtr pJsonRoot = sjson_parse((char*)pBuf.m_p, 0, 1);
    rc_error(pJsonRoot.m_p != NULL, E_FAIL);
    rc_error(IsJsonObject(pJsonRoot.m_p), E_FAIL);

    sjsonptr pJsonLogs = sjson_get_obj(pJsonRoot, Rule_log);
    rc_error(pJsonLogs != NULL, E_FAIL);
    rc_error(IsJsonObject(pJsonLogs), E_FAIL);

    sjsonptr pJsonTables = sjson_get_obj(pJsonLogs, Rule_Tables);
    rc_error(pJsonTables != NULL, E_FAIL);
    rc_error(IsJsonArray(pJsonTables), E_FAIL);

    int iloop = 0;
    for (iloop = 0; iloop < sjson_get_array_size(pJsonTables); iloop++) {
        sjsonptr JsItem = sjson_get_array_item(pJsonTables, iloop);

        if (IsJsonObject(JsItem)) {
            SyncTable(JsItem);
        }
    }

    return hr;
}
HRESULT CLogsImpl::SyncTable(sjsoncptr JsRoot)
{
    rc_error(JsRoot != NULL, E_FAIL);
    HRESULT hr = S_OK;
    ULONG uFieldCount = 0;
    CTableStruct* pTable = new CTableStruct();
    rc_error(pTable != NULL, E_FAIL);

    _lComPtr<ITableStruct> pITableStruct;
    hr = pTable->QueryInterface(IID_ITableStruct, (void**)&pITableStruct);
    rc_error(hr == S_OK, E_FAIL);

    sjsonptr pJsonTable = sjson_get_obj(JsRoot, Rule_Table);
    rc_error(IsJsonString(pJsonTable), E_FAIL);

    // pTable->SetTableName(pJsonTable->valuestring);
    //  logi("SyncTable=>table_name=>%s", pJsonTable->valuestring);

    // hr = m_pILogDataBase->IsTableExist(pJsonTable->valuestring);
    // rc_error_log(hr == S_OK, E_FAIL, "Fields_Table_Exist_Faild")

    sjsonptr pJsonOp = sjson_get_obj(JsRoot, Rule_Op);
    rc_error(IsJsonNumber(pJsonOp), E_FAIL);

    // pTable->SetKeyValue(Rule_Op, pJsonOp->valueint);

    sjsonptr pJsonSave = sjson_get_obj(JsRoot, Rule_Save);
    if (IsJsonNumber(pJsonSave)) {
        // pTable->SetKeyValue(Rule_Op, pJsonSave->valueint);
    }

    sjsonptr pJsonFields = sjson_get_obj(JsRoot, Rule_Fields);
    rc_error(IsJsonArray(pJsonFields), E_FAIL);

    int iloop = 0;

    FieldSturct field;
    for (iloop = 0; iloop < sjson_get_array_size(pJsonFields); iloop++) {
        sjsonptr JsItem = sjson_get_array_item(pJsonFields, iloop);
        if (IsJsonObject(JsItem)) {
            s_memset(&field, 0, sizeof(FieldSturct));

            sjsonptr pJsonFieldsName = sjson_get_obj(JsItem, Rule_Fields_Name);
            rc_error_continue(IsJsonString(pJsonFieldsName));
            s_memcpy(&field.name, pJsonFieldsName->valuestring, LOG_FIELD_NAME_LEN);

            sjsonptr pJsonFieldsType = sjson_get_obj(JsItem, Rule_Fields_Type);
            rc_error_continue(IsJsonString(pJsonFieldsType));
            s_memcpy(&field.type, pJsonFieldsType->valuestring, LOG_FIELD_TYPE_LEN);

            sjsonptr pJsonFieldsSize = sjson_get_obj(JsItem, Rule_Fields_Size);
            if (IsJsonNumber(pJsonFieldsSize)) {
                field.size = pJsonFieldsSize->valueint;
            }
            sjsonptr pJsonFieldsIndex = sjson_get_obj(JsItem, Rule_Fields_Index);
            if (IsJsonNumber(pJsonFieldsIndex)) {
                field.index = pJsonFieldsIndex->valueint;
            }

            // insert faild ????
            pTable->AddTableRecord(field);
        }
    }

    pTable->GetFieldsCount(uFieldCount);
    rc_error(uFieldCount > 0, E_FAIL);

    hr = m_pILogDataBase->SyncTable(pJsonTable->valuestring, pTable);
    rc_error(hr == S_OK, E_FAIL);

    return S_OK;
}

HRESULT CLogsImpl::Time_Thread_Run()
{
    return S_OK;
}
